﻿using System;
using System.Collections;
using System.Web.UI;

using DotNetNuke.ComponentModel;
using DotNetNuke.Entities.Host;
using DotNetNuke.Entities.Modules;
using DotNetNuke.Instrumentation;
using DotNetNuke.Security;
using DotNetNuke.Services.FileSystem;
using DotNetNuke.Services.Localization;
using SharePointFolderProvider.WSLists;
using System.Net;
using System.Xml;

namespace SharePointFolderProvider
{
    public partial class Settings : FolderMappingSettingsControlBase
    {
        private static readonly string encryptionKey = Host.GUID;
        private static readonly PortalSecurity portalSecurity = new PortalSecurity();
        private const string LISTS = @"_vti_bin/Lists.asmx";
        private const string USERNAME = "UserName";
        private const string DOMAIN = "Domain";
        private const string PASSWORD = "Password";
        private const string SHAREPOINTHOSTURL = "SharePointHostUrl";
        private const string DOCUMENTLIBRARY = "DocumentLibrary";
        private const string DOCUMENTLIBRARYVIEWNAME = "DocumentLibraryViewName";
        private Lists _listsService;

        public Lists ListsService
        {
            get
            {
                if (_listsService == null)
                {
                    _listsService = new Lists();
                }
                return _listsService;
            }
        }

        protected void ddlDocumentLibrary_SelectedIndexChanged(object sender, EventArgs e)
        {
            tbPassword.Attributes.Add("value", tbPassword.Text);
            if (ddlDocumentLibrary.SelectedIndex != 1)
                return;
            if (tbUserName.Text.Trim().Length > 0 && tbPassword.Text.Trim().Length > 0 && tbDomain.Text.Trim().Length > 0
                && tbSPUrl.Text.Trim().Length > 0)
            {
                ddlDocumentLibrary.Items.Clear();
                ddlDocumentLibrary.Items.Add(Localization.GetString("SelectDocumentLibrary", ((PortalModuleBase)this).LocalResourceFile));
                ddlDocumentLibrary.Items.Add(Localization.GetString("RefreshDocumentLibrary", ((PortalModuleBase)this).LocalResourceFile));
                LoadDocumentLibraries();
                if (ddlDocumentLibrary.Items.Count != 3)
                    return;
                ddlDocumentLibrary.SelectedValue = ddlDocumentLibrary.Items[2].Value;
            }
        }

        /// <summary>
        /// Get all document libraries
        /// </summary>
        private void LoadDocumentLibraries()
        {
            string userName;
            string passWord;
            string domain;
            string SPUrl;
            GetInputs(out userName, out passWord, out domain, out SPUrl);
            if ((userName != null) && (passWord != null) && (domain != null)
                && (SPUrl != null))
            {
                ListsService.Credentials = new NetworkCredential(userName, passWord, domain);
                ListsService.Url = SPUrl + LISTS;
                try
                {
                    XmlNode ndLists = ListsService.GetListCollection();
                    foreach (XmlElement elem in ndLists.ChildNodes)
                    {
                        if (elem.GetAttribute("ServerTemplate").Equals("101"))
                        {
                            // Get documentLibraryViewName 
                            ddlDocumentLibrary.Items.Add(elem.GetAttribute("Title"));
                            /** An example of DefaultViewUrl: 
                             * /communities/SiteAssets/Forms/AllItems.aspx */
                            string dlDefaultViewUrl = elem.GetAttribute("DefaultViewUrl");
                            /** An example of WebFullUrl: /communities */
                            string dlWebFullUrl = elem.GetAttribute("WebFullUrl");  
                            if (dlDefaultViewUrl.Length > 0 && dlWebFullUrl.Length > 0)
                            {
                                dlWebFullUrl += "/";
                                string documentLibraryViewName = dlDefaultViewUrl;
                                if (dlDefaultViewUrl.Contains(dlWebFullUrl))
                                    documentLibraryViewName = dlDefaultViewUrl.TrimStart(dlWebFullUrl.ToCharArray());
                                // Final process to get document library view name 
                                documentLibraryViewName = documentLibraryViewName.Substring(0, documentLibraryViewName.IndexOf('/'));
                                ddlDocumentLibraryViewName.Items.Add(documentLibraryViewName);
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    DnnLog.Error(ex);
                    throw;
                }
            }
        }

        /// <summary>
        /// Get user inputs
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="passWord"></param>
        /// <param name="domain"></param>
        /// <param name="SPUrl"></param>
        private void GetInputs(out string userName, out string passWord, out string domain, out string SPUrl)
        {
            userName = tbUserName.Text.Trim();
            passWord = tbPassword.Text.Trim();
            domain = tbDomain.Text.Trim();
            SPUrl = tbSPUrl.Text.Trim();
            if (!SPUrl.EndsWith("/"))
                SPUrl = SPUrl + "/";
        }

        protected void btnNewDocumentLibrary_Click(object sender, EventArgs e)
        {
            tbPassword.Attributes.Add("value", tbPassword.Text);
            SelectDocumentLibraryPanel.Visible = false;
            CreateDocumentLibraryPanel.Visible = true;
        }

        protected void btnSelectExistinDocumentLibrary_Click(object sender, EventArgs e)
        {
            tbPassword.Attributes.Add("value", tbPassword.Text);
            SelectDocumentLibraryPanel.Visible = true;
            CreateDocumentLibraryPanel.Visible = false;
        }

        /// <summary>
        /// Load Settings 
        /// </summary>
        /// <param name="folderMappingSettings"></param>
        public override void LoadSettings(Hashtable folderMappingSettings)
        {
            if (folderMappingSettings.ContainsKey(USERNAME))
                tbUserName.Text = portalSecurity.Decrypt(encryptionKey, folderMappingSettings[USERNAME].ToString());
            if (folderMappingSettings.ContainsKey(PASSWORD))
                tbPassword.Attributes["value"] = portalSecurity.Decrypt(encryptionKey, folderMappingSettings[PASSWORD].ToString());
            if (folderMappingSettings.ContainsKey(DOMAIN))
                tbDomain.Text = portalSecurity.Decrypt(encryptionKey, folderMappingSettings[DOMAIN].ToString());
            if (folderMappingSettings.ContainsKey(SHAREPOINTHOSTURL))
                tbSPUrl.Text = portalSecurity.Decrypt(encryptionKey, folderMappingSettings[SHAREPOINTHOSTURL].ToString());    
        }

        public override void UpdateSettings(int folderMappingID)
        {
            ((Control)this).Page.Validate();
            if (!((Control)this).Page.IsValid)
                throw new Exception();
            IFolderMappingController instance = ComponentBase<IFolderMappingController, FolderMappingController>.Instance;
            FolderMappingInfo folderMapping = instance.GetFolderMapping(folderMappingID);
            folderMapping.FolderMappingSettings[USERNAME] = GetUserName();
            folderMapping.FolderMappingSettings[PASSWORD] = GetPassword();
            folderMapping.FolderMappingSettings[DOMAIN] = GetDomain();
            folderMapping.FolderMappingSettings[SHAREPOINTHOSTURL] = GetSPUrl();
            folderMapping.FolderMappingSettings[DOCUMENTLIBRARY] = GetDocumentLibrary();
            folderMapping.FolderMappingSettings[DOCUMENTLIBRARYVIEWNAME] = GetDocumentLibraryViewName();
            instance.UpdateFolderMapping(folderMapping);
        }

        /// <summary>
        /// Get document library name
        /// </summary>
        /// <returns></returns>
        private string GetDocumentLibrary()
        {
            string documentLibraryName;
            if (SelectDocumentLibraryPanel.Visible)
                documentLibraryName = ddlDocumentLibrary.SelectedValue;
            else
            {
                documentLibraryName = tbDocumentLibraryName.Text.Trim();
                CreateDocumentLibrary(documentLibraryName);
                if (documentLibraryName.EndsWith("/"))
                    documentLibraryName = documentLibraryName.TrimEnd('/');
            }
            return documentLibraryName;
        }

        /// <summary>
        /// Get document library view name
        /// </summary>
        /// <returns></returns>
        private string GetDocumentLibraryViewName()
        {
            string documentLibraryViewName;
            if (SelectDocumentLibraryPanel.Visible)
                documentLibraryViewName = ddlDocumentLibraryViewName.Items[ddlDocumentLibrary.SelectedIndex].Value;
            else
            {
                documentLibraryViewName = tbDocumentLibraryName.Text.Trim();
                if (documentLibraryViewName.EndsWith("/"))
                    documentLibraryViewName = documentLibraryViewName.TrimEnd('/');
            }
            return documentLibraryViewName;
        }

        /// <summary>
        /// Create document library
        /// </summary>
        /// <param name="documentLibraryName"></param>
        private void CreateDocumentLibrary(string documentLibraryName)
        {
            string userName;
            string passWord;
            string domain;
            string SPUrl;
            GetInputs(out userName, out passWord, out domain, out SPUrl);
            if ((userName != null) && (passWord != null) && (domain != null)
                && (SPUrl != null))
            {
                ListsService.Credentials = new NetworkCredential(userName, passWord, domain);
                ListsService.Url = SPUrl + LISTS;
                try
                {
                    // Assign document library name to documentLibraryViewName
                    tbDocumentLibraryViewName.Text = documentLibraryName;
                    // Process documentLibraryName
                    string processedDocumentLibraryName = documentLibraryName;
                    if (documentLibraryName.EndsWith("/"))
                        processedDocumentLibraryName = documentLibraryName.TrimEnd('/');
                    // Document Library 101
                    ListsService.AddList(processedDocumentLibraryName, "New Document Library", 101);
                }
                catch (Exception ex)
                {
                    DnnLog.Error(ex);
                    tbErrorMessage.Text = ex.ToString();
                    lblErrorMessage.Visible = true;
                    tbErrorMessage.Visible = true;
                    throw;
                }
            }
        }

        /// <summary>
        /// Get user name
        /// </summary>
        /// <returns></returns>
        private string GetUserName()
        {
            return portalSecurity.Encrypt(encryptionKey, tbUserName.Text.Trim());
        }

        /// <summary>
        /// Get password
        /// </summary>
        /// <returns></returns>
        private string GetPassword()
        {
            return portalSecurity.Encrypt(encryptionKey, tbPassword.Text.Trim());
        }

        /// <summary>
        /// Get domain name
        /// </summary>
        /// <returns></returns>
        private string GetDomain()
        {
            return portalSecurity.Encrypt(encryptionKey, tbDomain.Text.Trim());
        }

        /// <summary>
        /// Get sharepoint url 
        /// </summary>
        /// <returns></returns>
        private string GetSPUrl()
        {
            return portalSecurity.Encrypt(encryptionKey, tbSPUrl.Text.Trim());
        }
    }
}